﻿using System;
using System.Collections.Generic;
using System.Linq;
using WinRTFramework.Common;
using WinRTFramework.Contracts.Settings;
using WinRTFramework.FrameworkConfiguration;
using WinRTFramework.Interfaces.Contracts.Settings.View;
using WinRTFramework.Interfaces.Contracts.Settings.ViewModel;
using Windows.Foundation;
using Windows.UI.ApplicationSettings;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Media.Animation;

namespace WinRTFramework.FrameworkCore.Managers
{
    internal class SettingsManager
    {
        private IIoCAdapter iocAdapter;
        private readonly IViewViewModelMapper viewMapper;
        private List<ISupportPermanentSettingsFlyout> _permanentSettingsFlyouts;
        private readonly Frame frame;

        public SettingsManager(IIoCAdapter iocAdapter, IViewViewModelMapper viewMapper, Frame frame = null)
        {
            this.iocAdapter = iocAdapter;
            this.viewMapper = viewMapper;
            this.frame = frame ?? (Frame)Window.Current.Content;

            SettingsPane.GetForCurrentView().CommandsRequested += SettingsService_CommandsRequested;
            EvaluatePermanentSettings();
        }

        private void EvaluatePermanentSettings()
        {
            _permanentSettingsFlyouts = new List<ISupportPermanentSettingsFlyout>();

            foreach(var permanentSetting in iocAdapter.GetAllRegisteredTypesThatImplement<ISupportPermanentSettingsFlyout>())
            {
                _permanentSettingsFlyouts.Add((ISupportPermanentSettingsFlyout) iocAdapter.GetInstanceOfType(permanentSetting));
            }
        }

        void SettingsService_CommandsRequested(SettingsPane sender, SettingsPaneCommandsRequestedEventArgs args)
        {
            foreach (ISupportSettingsFlyout settingsFlyout in GetAllSettingsThatAreValidInCurrentContextOrdered())
            {
                ISupportSettingsFlyout localCopy = settingsFlyout;
                args.Request.ApplicationCommands.Add(new SettingsCommand(Guid.NewGuid().ToString(), settingsFlyout.Label, command => OnSettingOpening(command, localCopy)));
            }
        }

        private void OnSettingOpening(IUICommand command, ISupportSettingsFlyout settingsFlyout)
        {
            var viewType = this.viewMapper.GetViewTypeForViewModelType(settingsFlyout.GetType(), null);
            var view = this.iocAdapter.GetInstanceOfType(viewType);
            if (view != null && view is SettingsFlyout)
            {
                (view as SettingsFlyout).DataContext = settingsFlyout;
                (view as SettingsFlyout).Show();
            }
        }

        private IEnumerable<ISupportSettingsFlyout> GetAllSettingsThatAreValidInCurrentContextOrdered()
        {
            List<ISupportSettingsFlyout> allSettings = new List<ISupportSettingsFlyout>(_permanentSettingsFlyouts);

            var currentPage = this.frame.Content as Page;
            if (currentPage != null)
            {
                var contextSpecificSettingsProvider = currentPage.DataContext as ISupportContextSpecificSettings;
                if(contextSpecificSettingsProvider != null)
                {
                    allSettings.AddRange(contextSpecificSettingsProvider.GetSettingsFlyoutViewModels());
                }
            }

            return allSettings.OrderBy(k => k.DisplayOrder);
        }
    }
}
